package com.gitee.qdbp.jdbc.plugins;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import com.gitee.qdbp.able.convert.BeanToMapConverter;
import com.gitee.qdbp.able.convert.MapToBeanConverter;
import com.gitee.qdbp.able.convert.ObjectTypeConverter;
import com.gitee.qdbp.able.exception.ResourceNotFoundException;
import com.gitee.qdbp.able.jdbc.base.OrderByCondition;
import com.gitee.qdbp.able.jdbc.base.UpdateCondition;
import com.gitee.qdbp.able.jdbc.base.WhereCondition;
import com.gitee.qdbp.jdbc.model.DbType;
import com.gitee.qdbp.jdbc.model.DbVersion;
import com.gitee.qdbp.jdbc.model.OmitStrategy;
import com.gitee.qdbp.jdbc.result.RowToBeanMapper.FactoryOfTable;
import com.gitee.qdbp.jdbc.result.RowToBeanMapper.FactoryOfTables;
import com.gitee.qdbp.jdbc.result.RowToMapMapper;
import com.gitee.qdbp.jdbc.support.ConversionServiceAware;
import com.gitee.qdbp.jdbc.utils.InnerTools;
import com.gitee.qdbp.staticize.tags.base.Taglib;
import com.gitee.qdbp.tools.property.PropertyContainer;
import com.gitee.qdbp.tools.utils.Config;
import com.gitee.qdbp.tools.utils.ConvertTools;
import com.gitee.qdbp.tools.utils.PropertyTools;
import com.gitee.qdbp.tools.utils.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.ConversionService;

/**
 * 插件中心
 *
 * @author zhaohuihua
 * @version 190601
 */
public class DbPluginContainer {

    private static final Logger log = LoggerFactory.getLogger(DbPluginContainer.class);

    /** 全局实例 **/
    private static DbPluginContainer DEFAULTS;

    /**
     * 获取全局实例<br>
     * 正确的操作顺序是先调DbPluginContainer.init(), 再使用DbPluginContainer.defaults()<br>
     * 如果不调init()也可以使用defaults(), 但此时使用的是内部默认实例<br>
     * 如果先使用defaults()再调init(), 则init之前使用内部默认实例, init之后使用init传入的全局实例<br>
     * 内部默认实例详见checkAndSetDefaultProperty()
     * 
     * @return 全局实例
     */
    public static DbPluginContainer defaults() {
        if (DEFAULTS == null) {
            DEFAULTS = InnerInstance.INSTANCE;
        }
        return DEFAULTS;
    }

    /**
     * 静态内部类单例模式, 同时解决延迟加载和并发问题(缺点是无法传参)<br>
     * 加载外部类时, 不会加载内部类, 也就不会创建实例对象;<br>
     * 只有DEFAULTS==null调用InnerInstance.INSTANCE时才会加载静态内部类;<br>
     * 加载类是线程安全的, 虚拟机保证只会装载一次内部类, 不会出现并发问题<br>
     *
     * @author zhaohuihua
     * @version 20200129
     */
    public static class InnerInstance {

        public static final DbPluginContainer INSTANCE = new DbPluginContainer();
        static {
            INSTANCE.init();
        }
    }

    private final DbPluginHelper pluginHelper;

    public DbPluginContainer() {
        this.pluginHelper = new DbPluginHelper(this);
    }

    public DbPluginHelper helper() {
        return pluginHelper;
    }

    public void init() {
        DbPluginInitTools.checkAndSetDefaultProperty(this);
    }

    /** 初始化全局实例, 应在第1次调用defaults()之前执行 **/
    public static void init(DbPluginContainer container) {
        if (DEFAULTS == container) {
            return;
        }
        if (DEFAULTS != null) {
            // @formatter:off
            // 正确的操作顺序是先调DbPluginContainer.init(), 再使用DbPluginContainer.defaults()
            log.debug("DbPluginContainer default instance already initialized, executing again will override the global instance.");
            // @formatter:on
        }
        DEFAULTS = container;
        // 检查和设置默认属性
        DbPluginInitTools.checkAndSetDefaultProperty(DEFAULTS);
    }

    protected void fillAwareValue(Object object) {
        if (object instanceof DbPluginHelper.Aware) {
            ((DbPluginHelper.Aware) object).setPlugins(pluginHelper);
        }
        if (conversionService != null && object instanceof ConversionServiceAware) {
            ((ConversionServiceAware) object).setConversionService(conversionService);
        }
    }

    private PropertyContainer sqlConfig;

    /** 获取配置项 **/
    public PropertyContainer getSqlConfig() {
        return sqlConfig;
    }

    /** 设置配置项 **/
    public void setSqlConfig(PropertyContainer sqlConfig) {
        this.sqlConfig = sqlConfig;
    }

    /** 设置配置项 ( key=value, 多个以换行符分隔 ) **/
    public void setSqlConfigString(String sqlConfig) {
        Properties properties = PropertyTools.loadByString(sqlConfig);
        this.sqlConfig = new Config(properties);
    }

    /** 设置配置项 **/
    public void setSqlConfigMaps(Map<String, String> sqlConfig) {
        this.sqlConfig = new Config(sqlConfig);
    }

    /** 可用的数据库类型 **/
    private List<DbType> availableDbTypes;

    /**
     * 获取可用的数据库类型
     * 
     * @return 数据库类型列表
     * @since 3.2.0
     */
    public List<DbType> getAvailableDbTypes() {
        return availableDbTypes;
    }

    /**
     * 设置可用的数据库类型
     * 
     * @param dbTypes 数据库类型列表
     * @since 3.2.0
     */
    public void setAvailableDbTypes(List<DbType> dbTypes) {
        this.availableDbTypes = dbTypes;
    }

    /**
     * 设置可用的数据库类型枚举类
     * 
     * @param classes 数据库类型枚举类
     * @since 3.2.0
     */
    public <E extends Enum<?>> void setAvailableDbTypeClasses(List<Class<E>> classes) {
        this.availableDbTypes = new ArrayList<>();
        for (Class<E> item : classes) {
            this.addAvailableDbTypeClass(item);
        }
    }

    /**
     * 设置可用的数据库类型枚举类
     * 
     * @param classNames 数据库类型枚举类, 多个以逗号或换行符分隔
     * @since 3.2.0
     */
    public void setAvailableDbTypeString(String classNames) {
        List<String> strings = InnerTools.splits(classNames);
        this.availableDbTypes = new ArrayList<>();
        for (String className : strings) {
            if (className == null || className.trim().length() == 0) {
                continue;
            }
            Class<?> clazz;
            try {
                clazz = Class.forName(className);
            } catch (ClassNotFoundException e) {
                throw new IllegalArgumentException("DbType Class not found: " + className);
            }
            if (clazz.isEnum()) {
                @SuppressWarnings("unchecked")
                Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) clazz;
                this.addAvailableDbTypeClass(enumClass);
            } else {
                throw new IllegalArgumentException("DbType class error, must be an enumeration class: " + className);
            }
        }
    }

    /**
     * 增加可用的数据库类型枚举类
     * 
     * @param clazz 数据库类型枚举类
     * @since 3.2.0
     */
    public <E extends Enum<?>> void addAvailableDbTypeClass(Class<E> clazz) {
        if (!DbType.class.isAssignableFrom(clazz)) {
            String msg = clazz.getName() + " is not assignable for " + DbType.class.getName();
            throw new IllegalArgumentException(msg);
        }
        E[] array = clazz.getEnumConstants();
        if (array.length == 0) {
            return;
        }
        // key=DbTypeLowerCase, value=DbTypeSourceDesc
        Map<String, String> oldDbTypes = new HashMap<>();
        if (this.availableDbTypes == null) {
            this.availableDbTypes = new ArrayList<>();
        } else {
            for (DbType item : this.availableDbTypes) {
                oldDbTypes.put(item.name().toLowerCase(), item.getClass().getName() + '.' + item.name());
            }
        }
        List<String> conflicts = new ArrayList<>();
        for (E item : array) {
            String dbKey = item.name().toLowerCase();
            if (oldDbTypes.containsKey(dbKey)) {
                String fmt = "%s.%s conflict with %s";
                conflicts.add(String.format(fmt, item.getClass().getName(), item.name(), oldDbTypes.get(dbKey)));
                continue;
            }
            this.availableDbTypes.add((DbType) item);
            oldDbTypes.put(dbKey, item.getClass().getName() + '.' + item.name());
        }
        if (!conflicts.isEmpty()) {
            log.warn(ConvertTools.joinToString(conflicts, "\n\t"));
        }
    }

    /** SQL标签库构造器 **/
    private Taglib.Creator sqlTaglibCreator;

    /**
     * 获取标签库构造器
     * 
     * @return 标签库构造器
     */
    public Taglib.Creator getSqlTaglibCreator() {
        return sqlTaglibCreator;
    }

    /**
     * 设置标签库构造器
     * 
     * @param taglibCreator 标签库构造器
     */
    public void setSqlTaglibCreator(Taglib.Creator taglibCreator) {
        this.sqlTaglibCreator = taglibCreator;
    }

    /**
     * 设置SQL标签库路径
     * 
     * @param taglibPath SQL标签库路径
     */
    public void setSqlTaglibPath(String taglibPath) {
        this.sqlTaglibCreator = new TaglibCreator(taglibPath);
    }

    private static class TaglibCreator implements Taglib.Creator {

        private final String taglibPath;

        public TaglibCreator(String taglibPath) {
            this.taglibPath = taglibPath;
        }

        @Override
        public Taglib create() {
            try {
                return new Taglib(taglibPath);
            } catch (ResourceNotFoundException e) { // 兼容旧版本
                String oldPath = "settings/dbtags/taglib.txt";
                String newPath = "settings/qdbc/qdbc.taglib.txt";
                if (!taglibPath.contains(oldPath)) {
                    throw e;
                } else {
                    return new Taglib(StringTools.replace(taglibPath, oldPath, newPath));
                }
            }
        }
    }

    /** JDBC数据类型转换: 将代码中写的数据类型转换为java.sql.Types中的数据类型 **/
    private JdbcDataTypeResolver jdbcDataTypeResolver;

    /** JDBC数据类型转换: 将代码中写的数据类型转换为java.sql.Types中的数据类型 **/
    public JdbcDataTypeResolver getJdbcDataTypeResolver() {
        return jdbcDataTypeResolver;
    }

    /** JDBC数据类型转换: 将代码中写的数据类型转换为java.sql.Types中的数据类型 **/
    public void setJdbcDataTypeResolver(JdbcDataTypeResolver jdbcDataTypeResolver) {
        this.jdbcDataTypeResolver = jdbcDataTypeResolver;
    }

    /** Spring的类型转换处理类 **/
    private ConversionService conversionService;

    /** Spring的类型转换处理类 **/
    public ConversionService getConversionService() {
        return conversionService;
    }

    /** Spring的类型转换处理类 **/
    public void setConversionService(ConversionService conversionService) {
        DbPluginInitTools.initDefaultConverter(conversionService);
        this.conversionService = conversionService;
    }

    /** 数据表和列信息扫描类 **/
    private TableInfoScans tableInfoScans;

    /** 数据表和列信息扫描类 **/
    public void setTableInfoScans(TableInfoScans tableInfoScans) {
        this.fillAwareValue(tableInfoScans);
        this.tableInfoScans = tableInfoScans;
    }

    /** 数据表和列信息扫描类 **/
    public TableInfoScans getTableInfoScans() {
        return tableInfoScans;
    }

    /** 多表关联列信息的解析器 **/
    private TablesFieldColumnParser tablesFieldColumnParser;

    /** 多表关联列信息的解析器 **/
    public TablesFieldColumnParser getTablesFieldColumnParser() {
        return tablesFieldColumnParser;
    }

    /** 多表关联列信息的解析器 **/
    public void setTablesFieldColumnParser(TablesFieldColumnParser tablesFieldColumnParser) {
        this.fillAwareValue(tablesFieldColumnParser);
        this.tablesFieldColumnParser = tablesFieldColumnParser;
    }

    /** 实体类字段数据填充策略 **/
    private EntityFieldFillStrategy entityFieldFillStrategy;
    /** 实体类逻辑删除数据状态填充策略 **/
    private EntityDataStateFillStrategy<?> dataStateFillStrategy;

    /** 实体类字段数据填充策略 **/
    public void setEntityFieldFillStrategy(EntityFieldFillStrategy entityFieldFillStrategy) {
        this.fillAwareValue(entityFieldFillStrategy);
        this.entityFieldFillStrategy = entityFieldFillStrategy;
    }

    /** 实体类逻辑删除数据状态填充策略 **/
    public EntityFieldFillStrategy getEntityFieldFillStrategy() {
        return entityFieldFillStrategy;
    }

    /** 实体类逻辑删除数据状态填充策略 **/
    public EntityDataStateFillStrategy<?> getEntityDataStateFillStrategy() {
        return dataStateFillStrategy;
    }

    /** 实体类逻辑删除数据状态填充策略 **/
    public void setEntityDataStateFillStrategy(EntityDataStateFillStrategy<?> dataStateFillStrategy) {
        this.fillAwareValue(dataStateFillStrategy);
        this.dataStateFillStrategy = dataStateFillStrategy;
    }

    /** 批量操作的省略策略 **/
    private OmitStrategy omitStrategyOfBatchSql;
    /** IN语句的省略策略 **/
    private OmitStrategy omitStrategyOfInSql;

    /** 获取批量操作的省略策略配置 **/
    public OmitStrategy getOmitStrategyOfBatchSql() {
        return omitStrategyOfBatchSql;
    }

    /** 设置批量操作的省略策略配置 **/
    public void setOmitStrategyOfBatchSql(OmitStrategy omitStrategy) {
        this.omitStrategyOfBatchSql = omitStrategy;
    }

    /**
     * 设置批量操作的省略策略配置
     * 
     * @param omitStrategy 省略策略字符串<br>
     *            minSize:keepSize, 以冒号分隔; 如8:3, 表示超过8项启用省略, 前后各保留3项<br>
     *            如果只有一个数字, 那这个数字就是minSize, 此时keepSize=3<br>
     */
    public void setOmitStrategyOfBatchSql(String omitStrategy) {
        this.omitStrategyOfBatchSql = OmitStrategy.of(omitStrategy);
    }

    /** 获取IN语句的省略策略配置 **/
    public OmitStrategy getOmitStrategyOfInSql() {
        return omitStrategyOfInSql;
    }

    /** 设置IN语句的省略策略配置 **/
    public void setOmitStrategyOfInSql(OmitStrategy omitStrategy) {
        this.omitStrategyOfInSql = omitStrategy;
    }

    /**
     * 设置IN语句的省略策略配置
     * 
     * @param omitStrategy 省略策略字符串<br>
     *            minSize:keepSize, 以冒号分隔; 如8:3, 表示超过8项启用省略, 前后各保留3项<br>
     *            如果只有一个数字, 那这个数字就是minSize, 此时keepSize=3<br>
     */
    public void setOmitStrategyOfInSql(String omitStrategy) {
        this.omitStrategyOfInSql = OmitStrategy.of(omitStrategy);
    }

    /** 命名转换接口 **/
    private JdbcNamingConverter namingConverter;

    /**
     * 命名转换接口
     * 
     * @return 命名转换接口
     * @since 3.3.0
     */
    public JdbcNamingConverter getNamingConverter() {
        return namingConverter;
    }

    /**
     * 命名转换接口
     * 
     * @param namingConverter 命名转换接口
     * @since 3.3.0
     */
    public void setNamingConverter(JdbcNamingConverter namingConverter) {
        this.fillAwareValue(namingConverter);
        this.namingConverter = namingConverter;
    }

    /** 数据库原生值的转换处理类(sysdate, CURRENT_TIMESTAMP等) **/
    private RawValueConverter rawValueConverter;

    /** 数据库原生值的转换处理类(sysdate, CURRENT_TIMESTAMP等) **/
    public RawValueConverter getRawValueConverter() {
        return rawValueConverter;
    }

    /** 数据库原生值的转换处理类(sysdate, CURRENT_TIMESTAMP等) **/
    public void setRawValueConverter(RawValueConverter rawValueConverter) {
        this.fillAwareValue(rawValueConverter);
        this.rawValueConverter = rawValueConverter;
    }

    /** 数据转换处理类 **/
    private VariableToDbValueConverter toDbValueConverter;

    /** 数据转换处理类 **/
    public void setToDbValueConverter(VariableToDbValueConverter toDbValueConverter) {
        this.fillAwareValue(toDbValueConverter);
        this.toDbValueConverter = toDbValueConverter;
    }

    /** 数据转换处理类 **/
    public VariableToDbValueConverter getToDbValueConverter() {
        return toDbValueConverter;
    }

    /** 对象类型转换处理类 **/
    private ObjectTypeConverter objectTypeConverter;

    /**
     * 对象类型转换处理类
     * 
     * @return 对象类型转换处理类
     * @since 3.3.0
     */
    public ObjectTypeConverter getObjectTypeConverter() {
        return objectTypeConverter;
    }

    /**
     * 对象类型转换处理类
     * 
     * @param objectTypeConverter 对象类型转换处理类
     * @since 3.3.0
     */
    public void setObjectTypeConverter(ObjectTypeConverter objectTypeConverter) {
        this.fillAwareValue(objectTypeConverter);
        this.objectTypeConverter = objectTypeConverter;
    }

    /** Row到Map的转换处理类 **/
    private RowToMapMapper rowToMapConverter;

    /** Row到Map的转换处理类 **/
    public void setRowToMapConverter(RowToMapMapper rowToMapConverter) {
        this.fillAwareValue(rowToMapConverter);
        this.rowToMapConverter = rowToMapConverter;
    }

    /** Row到Map的转换处理类 **/
    public RowToMapMapper getRowToMapConverter() {
        return rowToMapConverter;
    }

    /** Row到Bean的转换处理类的工厂类 (单表) **/
    private FactoryOfTable tableRowToBeanFactory;

    /**
     * Row到Bean的转换处理类的工厂类 (单表)
     * 
     * @return Row到Bean处理类工厂
     * @since 3.3.0
     */
    public FactoryOfTable getTableRowToBeanFactory() {
        return tableRowToBeanFactory;
    }

    /**
     * Row到Bean的转换处理类的工厂类 (单表)
     * 
     * @param tableRowToBeanFactory Row到Bean处理类工厂
     * @since 3.3.0
     */
    public void setTableRowToBeanFactory(FactoryOfTable tableRowToBeanFactory) {
        this.fillAwareValue(tableRowToBeanFactory);
        this.tableRowToBeanFactory = tableRowToBeanFactory;
    }

    /** Row到Bean的转换处理类的工厂类 (多表关联) **/
    private FactoryOfTables tablesRowToBeanFactory;

    /**
     * Row到Bean的转换处理类的工厂类 (多表关联)
     * 
     * @return Row到Bean处理类工厂
     * @since 3.3.0
     */
    public FactoryOfTables getTablesRowToBeanFactory() {
        return tablesRowToBeanFactory;
    }

    /**
     * Row到Bean的转换处理类的工厂类 (多表关联)
     * 
     * @param tablesRowToBeanFactory Row到Bean处理类工厂
     * @since 3.3.0
     */
    public void setTablesRowToBeanFactory(FactoryOfTables tablesRowToBeanFactory) {
        this.fillAwareValue(tablesRowToBeanFactory);
        this.tablesRowToBeanFactory = tablesRowToBeanFactory;
    }

    /** Map到JavaBean的转换处理类 **/
    private MapToBeanConverter mapToBeanConverter;

    /** Map到JavaBean的转换处理类 **/
    public void setMapToBeanConverter(MapToBeanConverter mapToBeanConverter) {
        this.fillAwareValue(mapToBeanConverter);
        this.mapToBeanConverter = mapToBeanConverter;
    }

    /** Map到JavaBean的转换处理类 **/
    public MapToBeanConverter getMapToBeanConverter() {
        return mapToBeanConverter;
    }

    /** JavaBean到Map的转换处理类 **/
    private BeanToMapConverter beanToMapConverter;

    /**
     * JavaBean到Map的转换处理类
     * 
     * @param beanToMapConverter 转换类
     * @since 3.2.0
     */
    public void setBeanToMapConverter(BeanToMapConverter beanToMapConverter) {
        this.fillAwareValue(beanToMapConverter);
        this.beanToMapConverter = beanToMapConverter;
    }

    /**
     * JavaBean到Map的转换处理类
     * 
     * @return 转换类
     * @since 3.2.0
     */
    public BeanToMapConverter getBeanToMapConverter() {
        return beanToMapConverter;
    }

    /** JavaBean到数据库条件的转换处理类 **/
    private DbConditionConverter dbConditionConverter;

    /** JavaBean到数据库条件的转换处理类 **/
    public void setDbConditionConverter(DbConditionConverter dbConditionConverter) {
        this.fillAwareValue(dbConditionConverter);
        this.dbConditionConverter = dbConditionConverter;
    }

    /** JavaBean到数据库条件的转换处理类 **/
    public DbConditionConverter getDbConditionConverter() {
        return dbConditionConverter;
    }

    /** 数据库运算符容器 **/
    private DbOperatorContainer operatorContainer;

    /** 数据库运算符容器 **/
    public void setOperatorContainer(DbOperatorContainer operatorContainer) {
        this.fillAwareValue(operatorContainer);
        this.operatorContainer = operatorContainer;
    }

    /** 数据库运算符容器 **/
    public DbOperatorContainer getOperatorContainer() {
        return operatorContainer;
    }

    /** SQL格式化接口 **/
    private SqlFormatter sqlFormatter;

    /** SQL格式化接口 **/
    public void setSqlFormatter(SqlFormatter sqlFormatter) {
        this.fillAwareValue(sqlFormatter);
        this.sqlFormatter = sqlFormatter;
    }

    /** SQL格式化接口 **/
    public SqlFormatter getSqlFormatter() {
        return sqlFormatter;
    }

    /** SQL替换处理接口 **/
    private SqlReplacer sqlReplacer;

    /** SQL替换处理接口 **/
    public SqlReplacer getSqlReplacer() {
        return sqlReplacer;
    }

    /** SQL替换处理接口 **/
    public void setSqlReplacer(SqlReplacer sqlReplacer) {
        this.fillAwareValue(sqlReplacer);
        this.sqlReplacer = sqlReplacer;
    }

    /** 数据库版本信息查询接口 **/
    private DbVersionFinder dbVersionFinder;

    /** 数据库版本信息查询接口 **/
    public void setDbVersionFinder(DbVersionFinder dbVersionFinder) {
        this.fillAwareValue(dbVersionFinder);
        this.dbVersionFinder = dbVersionFinder;
    }

    /** 数据库版本信息查询接口 **/
    public DbVersionFinder getDbVersionFinder() {
        return dbVersionFinder;
    }

    /** 数据库方言处理类创建接口 **/
    private SqlDialect.Creator sqlDialectCreator;

    /** 数据库方言处理类创建接口 **/
    public void setSqlDialectCreator(SqlDialect.Creator sqlDialectCreator) {
        this.fillAwareValue(sqlDialectCreator);
        this.sqlDialectCreator = sqlDialectCreator;
    }

    /** 数据库方言处理类创建接口 **/
    public SqlDialect.Creator getSqlDialectCreator() {
        return sqlDialectCreator;
    }

    /** SQL模板扫描接口 **/
    private SqlFileScanner sqlFileScanner;

    /**
     * 获取SQL模板扫描接口
     * 
     * @return SQL模板扫描接口
     * @since 3.2.0
     */
    public SqlFileScanner getSqlFileScanner() {
        return sqlFileScanner;
    }

    /**
     * 设置SQL模板扫描接口
     * 
     * @param sqlFileScanner SQL模板扫描接口
     * @since 3.2.0
     */
    public void setSqlFileScanner(SqlFileScanner sqlFileScanner) {
        this.fillAwareValue(sqlFileScanner);
        this.sqlFileScanner = sqlFileScanner;
    }

    /** SQL片断的选项 **/
    private SqlFragmentOptions sqlFragmentOptions;

    /**
     * 获取SQL片断选项
     * 
     * @return SQL片断选项
     * @since 3.2.10
     */
    public SqlFragmentOptions getSqlFragmentOptions() {
        return sqlFragmentOptions;
    }

    /**
     * 设置SQL片断选项
     * 
     * @param sqlFragmentOptions SQL片断选项
     * @since 3.2.10
     */
    public void setSqlFragmentOptions(SqlFragmentOptions sqlFragmentOptions) {
        this.fillAwareValue(sqlFragmentOptions);
        this.sqlFragmentOptions = sqlFragmentOptions;
    }

    /** 字段值校验处理类 **/
    private ColumnValueValidator columnValueValidator;

    /** 获取字段值校验处理类 **/
    public ColumnValueValidator getColumnValueValidator() {
        return columnValueValidator;
    }

    /** 设置字段值校验处理类 **/
    public void setColumnValueValidator(ColumnValueValidator columnValueValidator) {
        this.fillAwareValue(columnValueValidator);
        this.columnValueValidator = columnValueValidator;
    }

    /** 默认的批量新增处理类 **/
    private BatchInsertExecutor defaultBatchInsertExecutor;
    /** 默认的批量更新处理类 **/
    private BatchUpdateExecutor defaultBatchUpdateExecutor;
    /** 批量新增处理类列表 (通用的放前面,专用的放后面;反向匹配,后加入的优先匹配) **/
    private List<BatchInsertExecutor> batchInsertExecutors = new ArrayList<>();
    /** 批量更新处理类列表 (通用的放前面,专用的放后面;反向匹配,后加入的优先匹配) **/
    private List<BatchUpdateExecutor> batchUpdateExecutors = new ArrayList<>();

    /** 获取默认的批量新增处理类 (通用的放前面,专用的放后面;反向匹配,后加入的优先匹配) **/
    public BatchInsertExecutor getDefaultBatchInsertExecutor() {
        return defaultBatchInsertExecutor;
    }

    /** 设置默认的批量新增处理类 (通用的放前面,专用的放后面;反向匹配,后加入的优先匹配) **/
    public void setDefaultBatchInsertExecutor(BatchInsertExecutor batchInsertExecutor) {
        this.fillAwareValue(batchInsertExecutor);
        this.defaultBatchInsertExecutor = batchInsertExecutor;
    }

    /** 获取批量新增处理类列表 (通用的放前面,专用的放后面;反向匹配,后加入的优先匹配) **/
    public List<BatchInsertExecutor> getBatchInsertExecutors() {
        return this.batchInsertExecutors;
    }

    /** 设置批量新增处理类列表 (通用的放前面,专用的放后面;反向匹配,后加入的优先匹配) **/
    public void setBatchInsertExecutors(List<BatchInsertExecutor> batchInsertExecutors) {
        for (Object item : batchInsertExecutors) {
            fillAwareValue(item);
        }
        this.batchInsertExecutors = batchInsertExecutors;
    }

    /** 增加批量新增处理类 (后加入的优先匹配) **/
    public void addBatchInsertExecutor(BatchInsertExecutor batchInsertExecutor) {
        this.fillAwareValue(batchInsertExecutor);
        this.batchInsertExecutors.add(batchInsertExecutor);
    }

    /** 获取批量新增处理类 (后加入的优先匹配) **/
    public BatchInsertExecutor getBatchInsertExecutor(DbVersion version) {
        List<BatchInsertExecutor> executors = getBatchInsertExecutors();
        if (executors != null && !executors.isEmpty()) {
            for (int i = executors.size() - 1; i >= 0; i--) {
                BatchInsertExecutor item = executors.get(i);
                if (item.supports(version)) {
                    return item;
                }
            }
        }
        return getDefaultBatchInsertExecutor();
    }

    /** 获取默认的批量更新处理类 **/
    public BatchUpdateExecutor getDefaultBatchUpdateExecutor() {
        return defaultBatchUpdateExecutor;
    }

    /** 设置默认的批量更新处理类 **/
    public void setDefaultBatchUpdateExecutor(BatchUpdateExecutor batchUpdateExecutor) {
        this.fillAwareValue(batchUpdateExecutor);
        this.defaultBatchUpdateExecutor = batchUpdateExecutor;
    }

    /** 获取批量更新处理类列表 (通用的放前面,专用的放后面;反向匹配,后加入的优先匹配) **/
    public List<BatchUpdateExecutor> getBatchUpdateExecutors() {
        return this.batchUpdateExecutors;
    }

    /** 设置批量更新处理类列表 (通用的放前面,专用的放后面;反向匹配,后加入的优先匹配) **/
    public void setBatchUpdateExecutors(List<BatchUpdateExecutor> batchUpdateExecutors) {
        for (Object item : batchUpdateExecutors) {
            fillAwareValue(item);
        }
        this.batchUpdateExecutors = batchUpdateExecutors;
    }

    /** 增加更新处理类 (后加入的优先匹配) **/
    public void addBatchUpdateExecutor(BatchUpdateExecutor batchUpdateExecutor) {
        this.fillAwareValue(batchUpdateExecutor);
        this.batchUpdateExecutors.add(batchUpdateExecutor);
    }

    /** 获取批量修改处理类 (后加入的优先匹配) **/
    public BatchUpdateExecutor getBatchUpdateExecutor(DbVersion version) {
        List<BatchUpdateExecutor> executors = getBatchUpdateExecutors();
        if (executors != null && !executors.isEmpty()) {
            for (int i = executors.size() - 1; i >= 0; i--) {
                BatchUpdateExecutor item = executors.get(i);
                if (item.supports(version)) {
                    return item;
                }
            }
        }
        return getDefaultBatchUpdateExecutor();
    }

    /** Where条件的自定义条件构造器 **/
    private final List<WhereSqlBuilder<? extends WhereCondition>> whereSqlBuilders = new ArrayList<>();

    /** 增加Where条件的自定义条件构造器 **/
    public <T extends WhereCondition> void addWhereSqlBuilder(WhereSqlBuilder<T> builder) {
        this.fillAwareValue(builder);
        whereSqlBuilders.add(builder);
    }

    /** 设置Where条件的自定义条件构造器 **/
    public <T extends WhereCondition> void setWhereSqlBuilders(List<WhereSqlBuilder<T>> builders) {
        for (Object item : builders) {
            fillAwareValue(item);
        }
        whereSqlBuilders.clear();
        whereSqlBuilders.addAll(builders);
    }

    /** 获取Where条件的自定义条件构造器 **/
    // JDK8+
    // public <T extends WhereCondition, C extends T, B extends WhereSqlBuilder<T>> B getWhereSqlBuilder(Class<C> type) {
    @SuppressWarnings("unchecked")
    public <T extends WhereCondition, B extends WhereSqlBuilder<T>> B getWhereSqlBuilder(Class<T> type) {
        for (WhereSqlBuilder<? extends WhereCondition> item : whereSqlBuilders) {
            if (item.supported() == type) {
                return (B) item;
            }
        }
        for (WhereSqlBuilder<? extends WhereCondition> item : whereSqlBuilders) {
            if (item.supported() != null && item.supported().isAssignableFrom(type)) {
                return (B) item;
            }
        }
        return null;
    }

    /** 获取Where条件的自定义条件构造器列表 **/
    public List<WhereSqlBuilder<? extends WhereCondition>> getWhereSqlBuilders() {
        return whereSqlBuilders;
    }

    /** DbUpdate条件的自定义条件构造器 **/
    private final List<UpdateSqlBuilder<? extends UpdateCondition>> updateSqlBuilders = new ArrayList<>();

    /** 增加DbUpdate条件的自定义条件构造器 **/
    public <T extends UpdateCondition> void addUpdateSqlBuilder(UpdateSqlBuilder<T> builder) {
        this.fillAwareValue(builder);
        updateSqlBuilders.add(builder);
    }

    /** 设置DbUpdate条件的自定义条件构造器 **/
    public <T extends UpdateCondition> void setUpdateSqlBuilders(List<UpdateSqlBuilder<T>> builders) {
        for (Object item : builders) {
            fillAwareValue(item);
        }
        updateSqlBuilders.clear();
        updateSqlBuilders.addAll(builders);
    }

    /** 获取DbUpdate条件的自定义条件构造器 **/
    // JDK8+
    // public <T extends UpdateCondition, C extends T, B extends UpdateSqlBuilder<T>> B getUpdateSqlBuilder(Class<C> type) {
    @SuppressWarnings("unchecked")
    public <T extends UpdateCondition, B extends UpdateSqlBuilder<T>> B getUpdateSqlBuilder(Class<T> type) {
        for (UpdateSqlBuilder<? extends UpdateCondition> item : updateSqlBuilders) {
            if (item.supported() == type) {
                return (B) item;
            }
        }
        for (UpdateSqlBuilder<? extends UpdateCondition> item : updateSqlBuilders) {
            if (item.supported() != null && item.supported().isAssignableFrom(type)) {
                return (B) item;
            }
        }
        return null;
    }

    /** 获取DbUpdate条件的自定义条件构造器列表 **/
    public List<UpdateSqlBuilder<? extends UpdateCondition>> getUpdateSqlBuilders() {
        return updateSqlBuilders;
    }

    /** 排序条件的自定义条件构造器 **/
    private final List<OrderBySqlBuilder<? extends OrderByCondition>> orderBySqlBuilders = new ArrayList<>();

    /** 增加排序条件的自定义条件构造器 **/
    public <T extends OrderByCondition> void addOrderBySqlBuilder(OrderBySqlBuilder<T> builder) {
        this.fillAwareValue(builder);
        orderBySqlBuilders.add(builder);
    }

    /** 设置排序条件的自定义条件构造器 **/
    public <T extends OrderByCondition> void setOrderBySqlBuilders(List<OrderBySqlBuilder<T>> builders) {
        for (Object item : builders) {
            fillAwareValue(item);
        }
        orderBySqlBuilders.clear();
        orderBySqlBuilders.addAll(builders);
    }

    /** 获取排序条件的自定义条件构造器 **/
    @SuppressWarnings("unchecked")
    public <T extends OrderByCondition, B extends OrderBySqlBuilder<T>> B getOrderBySqlBuilder(Class<T> type) {
        for (OrderBySqlBuilder<? extends OrderByCondition> item : orderBySqlBuilders) {
            if (item.supported() == type) {
                return (B) item;
            }
        }
        for (OrderBySqlBuilder<? extends OrderByCondition> item : orderBySqlBuilders) {
            if (item.supported() != null && item.supported().isAssignableFrom(type)) {
                return (B) item;
            }
        }
        return null;
    }

    /** 获取排序条件的自定义条件构造器列表 **/
    public List<OrderBySqlBuilder<? extends OrderByCondition>> getOrderBySqlBuilders() {
        return orderBySqlBuilders;
    }
}
